package com.talkyun.utils.json;


import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.lang.reflect.Type;
import java.util.List;

public class JSON {
    public enum EnumMode {
        INTEGER, STRING, NAME
    }

    public static JSONObject parseObject(String text) {
        com.alibaba.fastjson.JSONObject json = com.alibaba.fastjson.JSON.parseObject(text);
        return new JSONObject(json);
    }

    public static JSONArray parseArray(String text) {
        com.alibaba.fastjson.JSONArray jarr = com.alibaba.fastjson.JSON.parseArray(text);
        return new JSONArray(jarr);
    }

    public static String toJsonString(Object obj) {
        return toJsonString(obj, EnumMode.STRING);
    }

    public static String toJsonStringWithNull(Object obj) {
        JSONSerializer serializer = new JSONSerializer(new SerializeWriter());
        serializer.config(SerializerFeature.WriteMapNullValue, true);
        return toJsonString(obj, EnumMode.STRING, serializer);
    }

    public static String toJsonString(Object obj, boolean prettyFormat) {
        return toJsonString(obj, prettyFormat, true);
    }

    public static String toJsonString(Object obj, boolean prettyFormat, boolean fieldSort) {
        SerializerFeature sf = fieldSort ? SerializerFeature.SortField : SerializerFeature.MapSortField;

        if (prettyFormat) {
            return com.alibaba.fastjson.JSON.toJSONString(obj, SerializerFeature.PrettyFormat, sf);
        } else {
            return com.alibaba.fastjson.JSON.toJSONString(obj, sf);
        }
    }

    public static String toJsonString(Object obj, EnumMode mode) {
        JSONSerializer serializer = new JSONSerializer(new SerializeWriter());
        return toJsonString(obj, mode, serializer);
    }

    private static String toJsonString(Object obj, EnumMode mode, JSONSerializer serializer) {
        if (mode == EnumMode.INTEGER) {
            serializer.config(SerializerFeature.WriteEnumUsingName, false);
            serializer.config(SerializerFeature.WriteEnumUsingToString, false);
        } else if (mode == EnumMode.STRING) {
            serializer.config(SerializerFeature.WriteEnumUsingName, false);
            serializer.config(SerializerFeature.WriteEnumUsingToString, true);
        } else if (mode == EnumMode.NAME) {
            serializer.config(SerializerFeature.WriteEnumUsingName, true);
            serializer.config(SerializerFeature.WriteEnumUsingToString, false);
        }

        return toJsonString(obj, serializer);
    }

    private static String toJsonString(Object obj, JSONSerializer serializer) {
        // global SerializerFeature
        serializer.config(SerializerFeature.DisableCircularReferenceDetect, true);

        try {
            serializer.write(obj);
            return serializer.toString();
        } finally {
            serializer.close();
        }
    }

    public static <T> T toJavaObject(String text, Class<T> clazz) {
        return com.alibaba.fastjson.JSON.parseObject(text, clazz);
    }

    public static <T> T toJavaObject(String text, Type type) {
        return com.alibaba.fastjson.JSON.parseObject(text, type);
    }

    public static <T> List<T> toJavaList(String text, Class<T> clazz) {
        return com.alibaba.fastjson.JSON.parseArray(text, clazz);
    }
}
